package main

import (
	// 导如 protoc 自动生成的包
	"context"
	"fmt"
	"gitee.com/visons/gopkg/log"
	"github.com/go-kratos/kratos/pkg/naming"
	"github.com/go-kratos/kratos/pkg/naming/discovery"
	pb "go_knowledge/micro-service/consignment/service/proto/consignment"
	"google.golang.org/grpc"
	"net"
	"time"
)

const (
	PORT = ":8888"
)

//
// 仓库接口
//
type IRepository interface {
	Create(consignment *pb.Consignment) (*pb.Consignment, error) // 存放新货物
	GetAll() []*pb.Consignment                                   // 获取仓库中所有的货物
}

//
// 我们存放多批货物的仓库，实现了 IRepository 接口
//
type Repository struct {
	consignments []*pb.Consignment
}

func (repo *Repository) Create(consignment *pb.Consignment) (*pb.Consignment, error) {
	repo.consignments = append(repo.consignments, consignment)
	return consignment, nil
}

func (repo *Repository) GetAll() []*pb.Consignment {
	return repo.consignments
}

//
// 定义微服务
//
type service struct {
	repo Repository
}

//
// 实现 consignment.pb.go 中的 ShippingServiceServer 接口
// 使 service 作为 gRPC 的服务端
//
// 托运新的货物
func (s *service) CreateConsignment(ctx context.Context, req *pb.Consignment) (*pb.Response, error) {
	// 接收承运的货物
	consignment, err := s.repo.Create(req)
	if err != nil {
		return nil, err
	}
	resp := &pb.Response{Created: true, Consignment: consignment}
	return resp, nil
}

// 获取目前所有托运的货物
func (s *service) GetConsignments(ctx context.Context, req *pb.GetRequest) (*pb.Response, error) {
	allConsignments := s.repo.GetAll()
	resp := &pb.Response{Consignments: allConsignments}
	return resp, nil
}

func main() {
	listener, err := net.Listen("tcp", PORT)
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	log.Printf("listen on: %s\n", PORT)
	server := grpc.NewServer()
	repo := Repository{}
	pb.RegisterShippingServiceServer(server, &service{repo})

	ExampleDiscovery_Register()

	if err := server.Serve(listener); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}

}

func ExampleDiscovery_Register() {

	dis := discovery.New(&discovery.Config{
		Nodes:  []string{"101.132.140.237:7171"},
		Zone:   "sh001",
		Env:    "dev",
		Region: "sh",
	})

	_, err := dis.Register(context.Background(), &naming.Instance{
		Zone:  "sh001",
		Env:   "dev",
		AppID: "demo",
		// Hostname:"", // NOTE: hostname 不需要，会优先使用discovery new时Config配置的值，如没有则从os.Hostname方法获取！！！
		Addrs:    []string{"grpc://127.0.0.1:8888"},
		LastTs:   time.Now().Unix(),
		Metadata: map[string]string{},
		Status:   1,
		Version:  "1.0",
		Hostname: "test1",
	})
	if err != nil {
		panic(err)
	}
	//defer cancel() // NOTE: 注意一般在进程退出的时候执行，会调用discovery的cancel接口，使实例从discovery移除
	fmt.Println("register")
	// Unordered output4
}
